package ecustom.clients.servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import ecustom.clients.util.JsonUtil;

public class HttpRequestUtil {

	private final static Logger log = Logger.getLogger(HttpRequestUtil.class);

	/**
	 * 发送HttpPost请求（from-data）。
	 * @param strURL
	 * @param params
	 * @return
	 */
	public static String post(String url, Map<String, String> params) throws Exception{
		PrintWriter out = null;
		BufferedReader in = null;
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
			
			// 设置发送POST请求
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setRequestMethod("POST"); // 设置请求方式
			
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			
			out = new PrintWriter(conn.getOutputStream());	// 获取URLConnection对象对应的输出流
			
			// 发送请求参数
			StringBuilder sb = new StringBuilder();
			for (String key : params.keySet()) {
				sb.append("&").append(key).append("=").append(params.get(key));
			}
			if (sb.length() > 0) {
				out.print(sb.substring(1));
			}
			
			
			out.flush();	// flush输出流的缓冲
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			sb = new StringBuilder();
			while ((line = in.readLine()) != null) {
				sb.append(line);
			}
			return sb.toString();
		} catch (Exception e) {
			 log.error("发送Post请求失败", e);
		} finally{
			try { if (out != null) out.close(); } catch(Exception e) { log.error("out.close()", e);}
			try { if (in != null) in.close(); } catch(Exception e) { log.error("in.close()", e);}
		}
		return "error";
	}


	/**
	 * 发送HttpPost请求（raw-json）。
	 * @param strURL 服务地址
	 * @param params 请求数据
	 * @param logIO 是否打印输入输出
	 */
	public static Map<String, Object> postJson(String strURL, Object params) {
		log.info("requestUrl = " + strURL);
		Map<String, Object> dataMap = new HashMap<String, Object>();
		try {
			URL url = new URL(strURL);// 创建连接
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setInstanceFollowRedirects(true);
			conn.setRequestMethod("POST"); // 设置请求方式
			conn.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
			conn.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			conn.connect();
			OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // utf-8编码
			if (params != null) {
				String inputJson = JsonUtil.toJson(params);
				log.info("inputJson = " + inputJson);	
				out.append(inputJson);
			}
			out.flush();
			out.close();
			log.info("hear:"+JsonUtil.toJson(conn.getHeaderFields().get("Set-Cookie")));
			int code = conn.getResponseCode();
			InputStream is = null;
			if (code == 200) {
				is = conn.getInputStream();
			} else {
				is = conn.getErrorStream();
			}

			// 读取响应
			int length = (int) conn.getContentLength();// 获取长度
			if (length != -1) {
				byte[] data = new byte[length];
				byte[] temp = new byte[512];
				int readLen = 0;
				int destPos = 0;
				while ((readLen = is.read(temp)) > 0) {
					System.arraycopy(temp, 0, data, destPos, readLen);
					destPos += readLen;
				}
				String result = new String(data, "UTF-8"); // utf-8编码
				log.info("outputJson = " + result);
				dataMap.put("Cookie", conn.getHeaderFields().get("Set-Cookie"));
				dataMap.put("resule", result);
			}

		} catch (IOException e) {
			log.error("Exception occur when send http post request!", e);
		}
		if(dataMap.isEmpty()) throw new RuntimeException("调用接口异常，请联系管理员！");
		return dataMap; // 自定义错误信息
	}
	
	/**
	 * 发送HttpPost请求（raw-json）。
	 * @param strURL 服务地址
	 * @param params 请求数据
	 * @param logIO 是否打印输入输出
	 * @return 成功:返回json字符串<br/>
	 */
	public static String postJson(String strURL, Object params, String cookie) {
		log.info("requestUrl = " + strURL);
		try {
			URL url = new URL(strURL);// 创建连接
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setInstanceFollowRedirects(true);
			conn.setRequestMethod("POST"); // 设置请求方式
			conn.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
			conn.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			conn.setRequestProperty("Cookie", cookie);	// 设置cookie
			conn.connect();
			OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // utf-8编码
			if (params != null) {
				String inputJson = JsonUtil.toJson(params);
				log.info("inputJson = " + inputJson);
				out.append(inputJson);
			}
			out.flush();
			out.close();

			int code = conn.getResponseCode();
			InputStream is = null;
			if (code == 200) {
				is = conn.getInputStream();
			} else {
				is = conn.getErrorStream();
			}

			// 读取响应
			int length = (int) conn.getContentLength();// 获取长度
			if (length != -1) {
				byte[] data = new byte[length];
				byte[] temp = new byte[512];
				int readLen = 0;
				int destPos = 0;
				while ((readLen = is.read(temp)) > 0) {
					System.arraycopy(temp, 0, data, destPos, readLen);
					destPos += readLen;
				}
				String result = new String(data, "UTF-8"); // utf-8编码
				log.info("inputJson = " + result);
				return result;
			}

		} catch (IOException e) {
			log.error("Exception occur when send http post request!", e);
		}
		return "{}"; // 自定义错误信息
	}
	
	
	/**
	 * 发送HttpPost请求（raw-json）。
	 * @param strURL 服务地址
	 * @param params 请求数据
	 * @param logIO 是否打印输入输出
	 * @return 成功:返回json字符串<br/>
	 */
	public static String postJson(String strURL, Object params, List<String> cookies) {
		log.info("requestUrl = " + strURL);
		try {
			URL url = new URL(strURL);// 创建连接
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setInstanceFollowRedirects(true);
			conn.setRequestMethod("POST"); // 设置请求方式
			conn.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
			conn.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			for(String cookie : cookies) {
				conn.setRequestProperty("Cookie", cookie);	// 设置cookie
			}
			conn.connect();
			OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // utf-8编码
			if (params != null) {
				String inputJson = JsonUtil.toJson(params);
				log.info("inputJson = " + inputJson);
				out.append(inputJson);
			}
			out.flush();
			out.close();

			int code = conn.getResponseCode();
			InputStream is = null;
			if (code == 200) {
				is = conn.getInputStream();
			} else {
				is = conn.getErrorStream();
			}

			// 读取响应
			int length = (int) conn.getContentLength();// 获取长度
			if (length != -1) {
				byte[] data = new byte[length];
				byte[] temp = new byte[512];
				int readLen = 0;
				int destPos = 0;
				while ((readLen = is.read(temp)) > 0) {
					System.arraycopy(temp, 0, data, destPos, readLen);
					destPos += readLen;
				}
				String result = new String(data, "UTF-8"); // utf-8编码
				log.info("inputJson = " + result);
				return result;
			}

		} catch (IOException e) {
			log.error("Exception occur when send http post request!", e);
		}
		return "{}"; // 自定义错误信息
	}
	
	/**
	 * 发送HttpPost请求（raw-json）。
	 * @param strURL 服务地址
	 * @param params 请求数据
	 * @param heardMap 请求头
	 * @return 成功:返回json字符串<br/>
	 */
	public static String postJson(String strURL, Object params, Map<String, String> heardMap) {
		log.info("requestUrl = " + strURL);
		try {
			URL url = new URL(strURL);// 创建连接
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setInstanceFollowRedirects(true);
			conn.setRequestMethod("POST"); // 设置请求方式
			conn.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
			conn.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			for(String key : heardMap.keySet()) {
				conn.setRequestProperty(key, heardMap.get(key));
			}
			conn.connect();
			OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // utf-8编码
			if (params != null) {
				String inputJson = JsonUtil.toJson(params);
				log.info("inputJson = " + inputJson);
				out.append(inputJson);
			}
			out.flush();
			out.close();

			int code = conn.getResponseCode();
			InputStream is = null;
			if (code == 200) {
				is = conn.getInputStream();
			} else {
				is = conn.getErrorStream();
			}

			// 读取响应
			int length = (int) conn.getContentLength();// 获取长度
			if (length != -1) {
				byte[] data = new byte[length];
				byte[] temp = new byte[512];
				int readLen = 0;
				int destPos = 0;
				while ((readLen = is.read(temp)) > 0) {
					System.arraycopy(temp, 0, data, destPos, readLen);
					destPos += readLen;
				}
				String result = new String(data, "UTF-8"); // utf-8编码
				log.info("inputJson = " + result);
				return result;
			}

		} catch (IOException e) {
			log.error("Exception occur when send http post request!", e);
		}
		return "{}"; // 自定义错误信息
	}
	
}
